#include "lm_conf_mediaplayer_wrapper.h"

namespace lm {
	void CALLBACK FuncMediaPlayOnMediaPlayOpenCB(
		int error, int identity, void* clientdata) {
		ConfMediaPlayerWrapper* wrapper = reinterpret_cast<ConfMediaPlayerWrapper*>(clientdata);
		wrapper->OnMediaPlayOpenCB(error, identity);
	}

	void CALLBACK FuncMediaPlayOnMediaPlayErrorCB(
		int error, int identity, void* clientdata) {
		ConfMediaPlayerWrapper* wrapper = reinterpret_cast<ConfMediaPlayerWrapper*>(clientdata);
		wrapper->OnMediaPlayErrorCB(error, identity);
	}

	void CALLBACK FuncMediaPlayOnMediaPlayCompleteCB(
		int identity, void* clientdata) {
		ConfMediaPlayerWrapper* wrapper = reinterpret_cast<ConfMediaPlayerWrapper*>(clientdata);
		wrapper->OnMediaPlayCompleteCB(identity);
	}

	void CALLBACK FuncMediaPlayOnMediaPlayDurationChangedCB(
		int identity, int64_t duration, void* clientdata) {
		ConfMediaPlayerWrapper* wrapper = reinterpret_cast<ConfMediaPlayerWrapper*>(clientdata);
		wrapper->OnMediaPlayDurationChangedCB(identity, duration);
	}

	void CALLBACK FuncMediaPlayOnMediaPlayPositionChangedCB(
		int identity, int64_t position, void* clientdata) {
		ConfMediaPlayerWrapper* wrapper = reinterpret_cast<ConfMediaPlayerWrapper*>(clientdata);
		wrapper->OnMediaPlayPositionChangedCB(identity, position);
	}

	void ConfMediaPlayerWrapper::OnMediaPlayOpenCB(int error, int identity) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnMediaPlayOpen(error, identity);
		}
	}

	void ConfMediaPlayerWrapper::OnMediaPlayErrorCB(int error, int identity) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnMediaPlayError(error, identity);
		}
	}

	void ConfMediaPlayerWrapper::OnMediaPlayCompleteCB(int identity) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnMediaPlayComplete(identity);
		}
	}

	void ConfMediaPlayerWrapper::OnMediaPlayDurationChangedCB(int identity, int64_t duration) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnMediaPlayDurationChanged(identity, duration);
		}
	}

	void ConfMediaPlayerWrapper::OnMediaPlayPositionChangedCB(int identity, int64_t position) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnMediaPlayPositionChanged(identity, position);
		}
	}

	ConfMediaPlayerWrapper::ConfMediaPlayerWrapper(native_object_t c_object)
		: c_object_(c_object) {
		ConfMediaPlayerCallback cb;
		memset(&cb, 0, sizeof(cb));
		cb.client_data_ = this;
		cb.OnMediaPlayComplete_ = FuncMediaPlayOnMediaPlayCompleteCB;
		cb.OnMediaPlayDurationChanged_ = FuncMediaPlayOnMediaPlayDurationChangedCB;
		cb.OnMediaPlayOpen_ = FuncMediaPlayOnMediaPlayOpenCB;
		cb.OnMediaPlayError_ = FuncMediaPlayOnMediaPlayErrorCB;
		cb.OnMediaPlayPositionChanged_ = FuncMediaPlayOnMediaPlayPositionChangedCB;
		lm_conf_mediaplay_set_callback(c_object_, &cb);
	}

	ConfMediaPlayerWrapper::~ConfMediaPlayerWrapper() {
	}

	void ConfMediaPlayerWrapper::AddObserver(Observer* observer) {
		if (std::find(observer_list_.begin(), observer_list_.end(), observer) == observer_list_.end())
			observer_list_.push_back(observer);
	}

	void ConfMediaPlayerWrapper::RemoveObserver(Observer* observer) {
		ObserverList::iterator it = std::find(observer_list_.begin(), observer_list_.end(), observer);
		if (it != observer_list_.end())
			observer_list_.erase(it);
	}

	int ConfMediaPlayerWrapper::OpenURL(const char* url, int* identity) {
		return lm_conf_mediaplay_Open_url(c_object_, url, identity);
	}

	int ConfMediaPlayerWrapper::Open(const char* filename, int* identity) {
		return lm_conf_mediaplay_Open(c_object_, filename, identity);
	}

	int ConfMediaPlayerWrapper::Close(int identity) {
		return lm_conf_mediaplay_Close(c_object_, identity);
	}

	int ConfMediaPlayerWrapper::Play(int identity, int timeoutS/* = 5*/) {
		return lm_conf_mediaplay_Play(c_object_, identity, timeoutS);
	}

	int ConfMediaPlayerWrapper::Stop(int identity) {
		return lm_conf_mediaplay_Stop(c_object_, identity);
	}

	int ConfMediaPlayerWrapper::Pause(int identity) {
		return lm_conf_mediaplay_Pause(c_object_, identity);
	}

	int ConfMediaPlayerWrapper::PlayStatus(int identity, bool& running) {
		int v = 0;
		int ret = lm_conf_mediaplay_PlayStatus(c_object_, identity, &v);
		running = !!v;
		return ret;
	}

	int ConfMediaPlayerWrapper::StopStatus(int identity, bool& stopped) {
		int v = 0;
		int ret = lm_conf_mediaplay_StopStatus(c_object_, identity, &v);
		stopped = !!v;
		return ret;
	}

	int ConfMediaPlayerWrapper::PauseStatus(int identity, bool& paused) {
		int v = 0;
		int ret = lm_conf_mediaplay_PauseStatus(c_object_, identity, &v);
		paused = !!v;
		return ret;
	}

	int ConfMediaPlayerWrapper::GetCurrentPosition(int identity, int64_t& positionMS) {
		return lm_conf_mediaplay_GetCurrentPosition(c_object_, identity, &positionMS);
	}

	int ConfMediaPlayerWrapper::SetCurrentPosition(int identity, int64_t positionMS) {
		return lm_conf_mediaplay_SetCurrentPosition(c_object_, identity, positionMS);
	}

	int ConfMediaPlayerWrapper::GetDuration(int identity, int64_t& durationMS) {
		return lm_conf_mediaplay_GetDuration(c_object_, identity, &durationMS);
	}

}